package models;

import java.awt.Image;
import java.io.File;
import java.util.*;

import javax.persistence.*;

import org.apache.commons.mail.EmailException;

import play.data.validation.Required;
import play.db.jpa.*;

/**
 * Organization Entity,Used for creating organizations in the system
 * 
 * @author Sara Assem
 */

@Entity
public class Organization extends Model {
	@OneToMany(mappedBy = "organization")
	public List<Permission> permission;

	/**
	 * the organization name
	 */
	@Required
	public String name;
	/**
	 * the organization email
	 */

	@Required
	public String email;

	/**
	 * the organization online address
	 */

	@Required
	public String address;

	/**
	 * the organization Description
	 */

	@Required
	@Lob
	public String description;

	/**
	 * the ideas posted on it directly
	 * 
	 * @author Ghada Abu Shady
	 */
	@OneToMany(mappedBy = "organization", cascade = CascadeType.ALL)
	public List<Idea> AirIdeas;

	/**
	 * tags of certain organization one organiation has many tags, while tag
	 * belong to one organization only
	 * 
	 * @author Ghada Abu Shady
	 */
	@OneToMany(mappedBy = "organization", cascade = CascadeType.ALL)
	public List<Tag> tags;

	/**
	 * the organization Category
	 */

	public String category;
	/**
	 * the organization Display picture
	 */
	public Blob picture;

	/**
	 * the organization CreationDate
	 */
	public Date creationDate;
	/**
	 * Any related document for the organization
	 */
	public File document;
	/**
	 * the organization type whether secret or public or private
	 */
	public String type = "Public"; // Default is public by Mohamed Abdel Kader

	/**
	 * the organization has several number of User subscribed to it
	 * 
	 * @author Sara Assem
	 */
	@ManyToMany
	@JoinTable(name = "Organizationsubscribers")
	public List<User> subscribers;
	
	@ManyToMany
	@JoinTable(name = "OrganizationblockedRequesters")
	public List<User> blockedRequesters;
	/**
	 * returns the list of subscribers in the organization
	 * 
	 * @author Sara Assem
	 * @return list of users of subscribers
	 */

	public List<User> getSubscribers() {
		return subscribers;
	}
	/**
	 * the organization can recieve many relation name request and the
	 * relationRequest only sent to the one organization
	 * 
	 * @author Menna Magdy
	 */
	@OneToMany(mappedBy = "organization", cascade = CascadeType.ALL)
	public List<RelationRequest> receiveRelations;
	/**
	 * the organization can have many relation Names
	 * 
	 * @author Menna Magdy
	 */
	@OneToMany(mappedBy = "organization")
	public List<RelationNames> relationNameList;
	/**
	 * the organization can have many relations
	 * 
	 * @author Menna Magdy
	 */
	@ManyToMany(mappedBy = "organization")
	public List<Relation> relationList;
	/**
	 * the organization can have only one lead
	 * 
	 * @author Sara Assem
	 */

	@ManyToOne
	public User lead;
	/**
	 * the organization can have many entities
	 * 
	 * @author Sara Assem
	 */

	@OneToMany(mappedBy = "organization", cascade = CascadeType.ALL)
	public List<Entities> allEntities;
	/**
	 * the organization can have many users
	 * 
	 * @author Sara Assem
	 */
	@ManyToMany
	@JoinTable(name = "Organizationusers")
	public List<User> orgMembers;
	/**
	 * the organization can have many blocked users
	 * 
	 * @author Noha wafa
	 */
	@ManyToMany
	@JoinTable(name = "blockedUsers")
	public List<User> blockedUsers;
	/**
	 * the organization enables users to tag or not
	 * 
	 * @author Amr El Salanekly
	 */

	public boolean tagging;
	@ManyToMany
	public List<User> requesters;

	/**
	 * Default constructor
	 * 
	 * @param name
	 *            the name of the organization
	 * @param email
	 *            the email of the organization
	 * @param address
	 *            the address of the organization
	 * @param description
	 *            the description of the organization
	 * @param type
	 *            the type of the organization
	 */

	public Organization(String name, String email, String address,
			String description, String type, User user) {
		this.name = name;
		this.email = email;
		this.address = address;
		this.description = description;
		this.creationDate = new Date();
		this.type = type;
		this.relationList = new ArrayList<Relation>();
		this.relationNameList = new ArrayList<RelationNames>();
		this.receiveRelations = new ArrayList<RelationRequest>();
		this.subscribers = new ArrayList<User>();
		this.orgMembers = new ArrayList<User>();
		this.lead = user;
		this.orgMembers.add(lead);
		lead.UsersOrg.add(this);
		subscribers.add(lead);
		this.AirIdeas = new ArrayList<Idea>();
		this.tags = new ArrayList<Tag>();
		this.permission = new ArrayList<Permission>();
		// this.perm = new PermissionUserOrganization();
		this.allEntities = new ArrayList<Entities>();
		this.blockedRequesters=new ArrayList<User>();

		if (this.type == "private") {
			requesters = new ArrayList<User>();

		}

	}

	/**
	 * returns all the organizations on the system
	 * 
	 * @author Sara Assem
	 */
	public static List<Organization> getOrganizations() {
		List<Organization> organizationList = Organization.findAll();
		return (organizationList);
	}

	/**
	 * creates a new relationName then add this relationName to the
	 * RelationNameList of that organization
	 * 
	 * @author Menna Magdy
	 * @author Mai Selwanes only for log statement
	 * 
	 * @param newName
	 *            the new relation name requested
	 * @return boolean identifies whether relation name is added or not
	 */
	public boolean addRelationName(String newName) {

		for (int i = 0; i < this.relationNameList.size(); i++) {
			if (this.relationNameList.get(i).relationName
					.equalsIgnoreCase(newName))
				return false;
		}
		RelationNames newRelationName = new RelationNames(this, newName).save();
		this.relationNameList.add(newRelationName);
		this.save();
		Log log = new Log(this, this.lead, "has added a new relation name"
				+ newName);
		log.save();

		return true;
	}

	/**
	 * creates a new relation between entities in this organization then add
	 * this relation to RelationList of the organization and the RelationList of
	 * the User..the method notifies the organizationLead of the new relation
	 * 
	 * @author Menna Magdy
	 * @param user
	 *            the user that added the relation
	 * @param relationName
	 *            the name of the new relation
	 * @param source
	 *            the source entity of the new relation
	 * @param destination
	 *            the destination entity of the new relation
	 * @return Relation the new relation created
	 */
	public Relation addEntitiesRelation(User user, String relationName,
			String source, String destination) {
		Relation newRelation = new Relation(this, user, relationName, source,
				destination, "entity").save();
		this.relationList.add(newRelation);
		user.relationList.add(newRelation);
		newRelation.addEntitiesRelation(this.allEntities);
		this.save();
		user.save();
		String action = "A new Relation between entity " + source
				+ "and entity " + destination + "called " + relationName
				+ " by " + user.name;
		ArrayList<User> receiver = new ArrayList<User>();
		receiver.add(this.lead);

		user.sendNotificationWithType(action, receiver, "Relation",
				newRelation.id); 
		return (newRelation);
	}

	/**
	 * creates a new relation between topics then add this relation to
	 * RelationList of the organization and the RelationList of the User..the
	 * method notifies the organizationLead of the new relation
	 * 
	 * @author Menna Magdy
	 * @param user
	 *            the user that added the relation
	 * @param relationName
	 *            the name of the new relation
	 * @param source
	 *            the source topic of the new relation
	 * @param destination
	 *            the destination topic of the new relation
	 * @return Relation the new relation created
	 */
	public Relation addTopicRelation(User user, String relationName,
			String source, String destination) {
		Relation newRelation = new Relation(this, user, relationName, source,
				destination, "topic").save();
		this.relationList.add(newRelation);
		user.relationList.add(newRelation);
		List<Entities> entity = this.allEntities;
		List<Topic> topic = new ArrayList<Topic>();
		for (int i = 0; i < entity.size(); i++) {
			for (int j = 0; j < entity.get(i).topics.size(); j++)
				topic.add(entity.get(i).topics.get(j));
		}
		newRelation.addTopicRelation(topic);
		this.save();
		user.save();
		String action = "A new Relation between topic " + source
				+ " and topic " + destination + " called " + relationName
				+ " by " + user.name;
		ArrayList<User> receiver = new ArrayList<User>();
		receiver.add(this.lead);

		user.sendNotificationWithType(action, receiver, "Relation",
				newRelation.id);

		return (newRelation);

	}

	/**
	 * creates a new relation between tags then add this relation to
	 * relationList of the organization and the relationList of the User..the
	 * method notifies the organizationLead of the new relation
	 * 
	 * @author Menna Magdy
	 * @param user
	 *            the user that added the relation
	 * @param relationName
	 *            the name of the new relation
	 * @param source
	 *            the source tag of the new relation
	 * @param destination
	 *            the destination tag of the new relation
	 * @return Relation the new relation created
	 */
	public Relation addTagRelation(User user, String relationName,
			String source, String destination) {
		Relation newRelation = new Relation(this, user, relationName, source,
				destination, "tag").save();
		this.relationList.add(newRelation);
		user.relationList.add(newRelation);
		newRelation.addTagRelation(this.tags);
		this.save();
		user.save();
		String action = "A new Relation between Tag " + source + "and Tag "
				+ destination + "called " + relationName + " by " + user.name;
		ArrayList<User> receiver = new ArrayList<User>();
		receiver.add(this.lead);

		user.sendNotificationWithType(action, receiver, "Relation",
				newRelation.id);
		return (newRelation);
	}

	/**
	 * sends a request for creating a new Relation Name using RelationRequest
	 * class
	 * 
	 * @author Menna Magdy
	 * @param sender
	 *            The user who request the relation name.
	 * @param reciever
	 *            The user who will confirm/reject the request
	 *            "organizationLead"
	 * @param relationName
	 *            the relation name that requested
	 * @return boolean identifies whether the relation is existed "true" or not
	 *         "false"
	 */
	public boolean addRelationRequest(User sender, String relationName) {
		for (int i = 0; i < this.relationNameList.size(); i++) {
			if (this.relationNameList.get(i).relationName
					.equalsIgnoreCase(relationName))
				return false;
		}

		sender.sendRelationRequest(this, relationName);

		return true;
	}

	/**
	 * checks whether the new relation is valid or not depending on checking if
	 * is there is an existing relation or there is a conflict relation or the
	 * source equals the destination
	 * 
	 * @param sender
	 *            The user who request the relation name.
	 * @param reciever
	 *            The user who will confirm/reject the request
	 *            "organizationLead"
	 * @param relationName
	 *            the relation name that requested
	 * @return String action that depends on some checks
	 * 
	 * @author Menna Magdy
	 */
	public String checkRelation(String relationName, String source,
			String destination, String type) {
		String action = "true";
		if (source.equalsIgnoreCase(destination))
			action = "*Source and destination are the same";
		else {
			for (int i = 0; i < this.relationList.size(); i++) {
				if (this.relationList.get(i).type.equalsIgnoreCase(type)) {
					if (this.relationList.get(i).relationName
							.equalsIgnoreCase(relationName)
							&& this.relationList.get(i).source
									.equalsIgnoreCase(source)
							&& this.relationList.get(i).destination
									.equalsIgnoreCase(destination)) {
						action = "*Same relation is existed";
						break;
					}
					if (this.relationList.get(i).relationName
							.equalsIgnoreCase(relationName)
							&& this.relationList.get(i).source
									.equalsIgnoreCase(destination)
							&& this.relationList.get(i).destination
									.equalsIgnoreCase(source)) {
						action = "*There is a relation conflicts this relation!!";
						break;
					}
				}
			}
		}
		return action;
	}

	/**
	 * checks whether the author can create this entities relation then checks
	 * if the new relation is valid or not by calling checkRelation method
	 * 
	 * @param author
	 *            The user who create the relation.
	 * @param source
	 *            the name of the source entity of the relation
	 * @param destination
	 *            the name of the source entity of the relation
	 * @param relationName
	 *            the relation name of the relation
	 * @return String action that depends on some checks
	 * @author Menna Magdy
	 */
	public String checkEntitiesRelation(User author, String source,
			String destination, String relationName) {
		List<Entities> entity = this.allEntities;
		Entities sourceEntity = null;
		Entities destinationEntity = null;
		for (int i = 0; i < entity.size(); i++) {
			if (entity.get(i).entityName.equalsIgnoreCase(source))
				sourceEntity = entity.get(i);
			if (entity.get(i).entityName.equalsIgnoreCase(destination))
				destinationEntity = entity.get(i);
		}
		String right = "false";
		Permission permission = Permission.find("user=? AND aUserType=?",
				author, "systemAdmin").first();
		if (permission != null)
			right = "true";
		if (author.equals(this.lead) && permission == null)
			right = "true";
		else {
			permission = Permission.find(
					"USER_ID=? AND ORGANIZATION_ID=? AND ENTITY_ID=?",
					author.id, this.id, sourceEntity.id).first();
			if (permission != null) {
				if (permission.createRelation == true)
					right = "true";
			} else {
				permission = Permission.find(
						"USER_ID=? AND ORGANIZATION_ID=? AND ENTITY_ID=?",
						author.id, this.id, destinationEntity.id).first();
				if (permission != null) {
					if (permission.createRelation == true)
						right = "true";
				}
			}
		}
		if (right == "false")
			return "Sorry, You are not permitted to do this action!!";
		String action = this.checkRelation(relationName, source, destination,
				"entity");
		if (action != "true")
			return action;
		return "go";
	}

	/**
	 * checks whether the author can create this topics relation then checks if
	 * the new relation is valid or not by calling checkRelation method
	 * 
	 * @param author
	 *            The user who create the relation.
	 * @param source
	 *            the name of the source topic of the relation
	 * @param destination
	 *            the name of the source topic of the relation
	 * @param relationName
	 *            the relation name of the relation
	 * @return String action that depends on some checks
	 * @author Menna Magdy
	 */
	public String checkTopicRelation(User author, String source,
			String destination, String relationName) {
		List<Entities> entity = this.allEntities;
		List<Topic> topic = new ArrayList<Topic>();
		for (int i = 0; i < entity.size(); i++) {
			for (int j = 0; j < entity.get(i).topics.size(); j++) {
				if (entity.get(i).topics.get(j).isLocked == false)
					topic.add(entity.get(i).topics.get(j));
			}
		}
		Relation relation = null;
		Topic sourceTopic = null;
		Topic destinationTopic = null;
		for (int i = 0; i < topic.size(); i++) {
			if (topic.get(i).title.equalsIgnoreCase(source))
				sourceTopic = topic.get(i);
			if (topic.get(i).title.equalsIgnoreCase(destination))
				destinationTopic = topic.get(i);
		}
		String right = "false";
		Permission permission = Permission.find("user=? AND aUserType=?",
				author, "systemAdmin").first();
		if (permission != null)
			right = "true";
		if (author.equals(this.lead) && permission == null)
			right = "true";
		else {
			permission = Permission.find(
					"USER_ID=? AND ORGANIZATION_ID=? AND ENTITY_ID=?",
					author.id, this.id, sourceTopic.entity.id).first();
			if (permission != null) {
				if (permission.createRelation == true)
					right = "true";
			} else {
				permission = Permission.find(
						"USER_ID=? AND ORGANIZATION_ID=? AND ENTITY_ID=?",
						author.id, this.id, destinationTopic.entity.id).first();
				if (permission != null) {
					if (permission.createRelation == true)
						right = "true";
				}
			}
		}
		if (right == "false")
			return "Sorry, You are not permitted to do this action!!";
		;
		String action = this.checkRelation(relationName, source, destination,
				"topic");
		if (action != "true")
			return action;

		return "go";
	}

	/**
	 * checks if the new relation is valid or not by calling checkRelation
	 * method then returns "go" if valid and if not valid returns the reason
	 * 
	 * @param author
	 *            The user who create the relation.
	 * @param source
	 *            the name of the source topic of the relation
	 * @param destination
	 *            the name of the source topic of the relation
	 * @param relationName
	 *            the relation name of the relation
	 * @return String action that depends on some checks
	 * @author Menna Magdy
	 */
	public String checkTagRelation(User author, String source,
			String destination, String relationName) {
		String action = this.checkRelation(relationName, source, destination,
				"tag");
		if (action != "true")
			return action;

		return "go";
	}

	/**
	 * takes a string name as a parameter and check whether there is another
	 * organization with the same name or not
	 * 
	 * @param name
	 *            the name of organization to compare to
	 * 
	 * @author Sara Assem
	 * @return boolean whether the name appears in the system or not
	 */
	public static boolean checkNameDuplication(String name, Long id) {
		List<Organization> orgs = Organization.getOrganizations();
		if (orgs.size() >= 0) {

			for (int i = 0; i < orgs.size(); i++) {

				if (orgs.get(i).name.equalsIgnoreCase(name)
						&& orgs.get(i).id == id) {
					return true;
				}

				if (orgs.get(i).name.equalsIgnoreCase(name)) {
					return false;
				}
			}

		}
		return true;
	}

	/**
	 * takes a user as a param and adds it to the list of subscriber of this
	 * organization
	 * 
	 * @param User
	 *            that should be added
	 * 
	 * @author Sara Assem
	 * @author Mai Selwanes only for log
	 */
	public void addUserToSubscribers(User user) {
		subscribers.add(user);
		Log log = new Log(this, user,
				" has been added to the list of subscribers of the organization");
		log.save();
	}

	/**
	 * takes a user as a param and removes it from the list of subscriber of
	 * this organization
	 * 
	 * @param User
	 *            that should be removed
	 * 
	 * @author Sara Assem
	 * @author Mai Selwanes only for log
	 */
	public void removeUserFromSubscribers(User user) {
		subscribers.remove(user);
		Log log = new Log(this, user,
				" has been removed from the list of subscribers of the organization");
		log.save();
	}

	public List<User> getOrgMembers() {
		return orgMembers;
	}

	/**
	 * returns all entities in the organization
	 * 
	 * @return A list of all entities in the organization
	 * @author Mai Abu-El Seoud
	 */
	public List<Entities> getEntities() {
		return allEntities;
	}

	/**
	 * checks whether the user is in the subscriber list of the organization or
	 * not
	 * 
	 * 
	 * @param User
	 *            user the user that we want to check is he in the list or not .
	 * @return boolean whether user in subscribers list
	 * @author Sara Assem
	 */
	public boolean userinSubscribers(User user) {

		for (User subscriber : this.subscribers) {
			if (user == subscriber)
				return true;

		}
		return false;
	}

	/**
	 * blockIdeaDeveloperInOrganization is a method that sends notification to
	 * all users of organization notifyimg them with blocking this ideadeveloper
	 * send notification to that ideadeveloper blocked with thereason of his
	 * blocking
	 * 
	 * 
	 * 
	 * @author Noha wafa
	 */
	public void blockIdeaDeveloperInOrganization() {
		User organizationLead = new User("email", "name", "pass", 8, true,
				true, false);
		User organizationUsers = new User("email", "name", "pass", 4, true,
				true, false);
		ArrayList<User> receiversOfNotification = new ArrayList<User>();
		receiversOfNotification.add(organizationUsers);

		organizationLead.sendNotificationWithType(
				"Mr. kaza is blocked because bla bla bla",
				receiversOfNotification, "reason", this.id);
		String note = organizationUsers.notifies.get(0).content;
		System.out.println(note);
		System.out.println(organizationUsers.unreadNotification);
		User ideaDeveloperBlocked = new User("email", "name", "pass", 8, true,
				true, false);

		receiversOfNotification.add(ideaDeveloperBlocked);
		organizationLead.sendNotificationWithType(
				"you are blocked bec bla bla bla", receiversOfNotification,
				"reason", this.id);
		String reason = organizationUsers.notifies.get(0).content;
		System.out.println(reason);
		System.out.println(ideaDeveloperBlocked.unreadNotification);

	}

	/**
	 * deleteEntityInOrganization() is a method that deletes existing entities
	 * in an organization.
	 * 
	 * @author Amr El Salanekly
	 * @author Mai Selwanes only for log statement
	 * 
	 * @param entity_id
	 *            the entity_id is the auto-generated identification of the
	 *            entity
	 */
	public void deleteEntity(long entity_id) {
			Entities entity = Entities.findById(entity_id);
			List<Topic> topicList = Topic.find("byEntity_id", entity_id).fetch();
			
			
			if(entity.relationList.size()!=0)
			{
				for(int i=0; i<entity.relationList.size();i++){
					entity.relationList.get(i).unassignEntityRelation();
				}
					
			}
			for(int k=0; k<topicList.size();k++){
				if(topicList.get(k).relationList.size()!=0)
				{
					for(int i=0;i<topicList.get(k).relationList.size();i++){
						topicList.get(k).relationList.get(i).unassignTopicRelation();
					}
				}
			}
			for (int i = 0; i < topicList.size(); i++) {
				List<Idea> ideaList = Idea.find("byTopic_id", topicList.get(i).id)
						.fetch();
				
				
				for (int j = 0; j < ideaList.size(); j++) {
					List <Comment> commentList = Comment.find("byIdea_id", ideaList.get(j).id).fetch();
					for (int k = 0; k < commentList.size(); k++){
						commentList.get(k).delete();
					}
					ideaList.get(j).delete();
				}
				topicList.get(i).delete();
			}
			entity.delete();

		}


	/**
	 * returns a list of all tags in an organization that have no ideas using
	 * them
	 * 
	 * @author Nesreen elgohary
	 */
	public List<Tag> unusedTags() {
		List<Tag> unusedTags = new LinkedList<Tag>();
		if (!this.tags.isEmpty()) {
			for (int counter = 0; counter < this.tags.size(); counter++) {
				if (this.tags.get(counter).Ideas.isEmpty()) {
					unusedTags.add(this.tags.get(counter));
				}
			}
		}
		return unusedTags;
	}

	/**
	 * adds an idea developer to become a member in a certain organization
	 * 
	 * @param user
	 *            The user that will be added to the organization
	 * @author Mai Abu-El Seoud
	 * @author Mai Selwanes only for log statement
	 */
	public void addUserToOrganization(User user) {
		this.orgMembers.add(user);
		this.save();
		Log log = new Log(this, user,
				" has been added to the organization's members");
		log.save();

	}

	/**
	 * checks if the user is already a member in the organization that he wants
	 * to join
	 * 
	 * @param user
	 *            the user that requests joining the organization
	 * @return returns boolean if he is already a member return true and else
	 *         returns false
	 * @author Mai Abu-El Seoud
	 */
	public boolean checkUser(User user) {
		boolean found = false;
		if (user == lead) {
			found = true;
		} else {
			for (int i = 0; i < orgMembers.size(); i++) {
				if (orgMembers.get(i) == user) {
					found = true;
				}
			}
		}
		return found;
	}

	/**
	 * removes a certain idea developer from the organization
	 * 
	 * @param user
	 *            The user that will be removed
	 * @author Mai Abu-El seoud
	 * @author Mai Selwanes only for log statement
	 */
	public void removeUser(User user) {
		orgMembers.remove(user);
		this.save();
		Log log = new Log(this, user,
				" has been removed from the organization's members");
		log.save();

	}

	/**
	 * sends an email to invite an unregistered user to be organizer in a
	 * certain entity by creating a new unregisteredInvitations
	 * 
	 * @param unemail
	 * @param sender
	 * @param type
	 * @param id
	 * @author Sara Assem
	 * @throws EmailException
	 */

	public void InviteUnRegisteredUsertobeOrganizer(String unemail,
			User sender, String type, Long id) throws EmailException {

		System.out.println("new mal1");
		boolean found = false;

		Entities entity = Entities.findById(id);
		Email email = new Email(
				"sara.assem@hotmail.com",
				unemail,
				"Invitation",
				"You are invited to be an organizer in organization"
						+ this.name
						+ "in"
						+ "entity"
						+ entity.entityName
						+ " ,If you want to register please go to localhost:9000");
		email.sendEmail();
		String msg = sender.name
				+ " would like to invite you to be an organizer " + "in "
				+ entity.entityName;

		List<UnRegisteredEmail> emails = UnRegisteredEmail.findAll();

		for (int i = 0; i < emails.size(); i++) {
			if (emails.get(i).email == unemail) {
				found = true;
			}
		}
		if (found == false) {
			UnRegisteredEmail newemail = new UnRegisteredEmail(unemail).save();

		}

		UnRegisteredEmail unregisteredemail = UnRegisteredEmail.find("email",
				unemail).first();

		UnregisteredInvitation invitation = new UnregisteredInvitation(msg,
				unregisteredemail, type, id);
		invitation.save();

	}

	/**
	 * sends an email to invite an unregistered user to be an idea developer in
	 * a certain organization by creating a new unregisteredInvitations
	 * 
	 * @param unemail
	 * @param sender
	 * @param type
	 * @param id
	 * @author Sara Assem
	 * @throws EmailException
	 */

	public void InviteUnRegisteredUser(String unemail, User sender,
			String type, Long id) throws EmailException {

		boolean found = false;

		Email email = new Email(
				"sara.assem@hotmail.com",
				unemail,
				"Invitation",
				"You are invited to be an idea developer in"
						+ this.name
						+ ",If you want to register please go to localhost:9000");
		email.sendEmail();

		String msg = sender.name
				+ " would like to invite you to be an ideadeveloper " + "in "
				+ this.name;

		List<UnRegisteredEmail> emails = UnRegisteredEmail.findAll();

		for (int i = 0; i < emails.size(); i++) {
			if (emails.get(i).email == unemail) {
				found = true;
			}
		}
		if (found == false) {
			UnRegisteredEmail newemail = new UnRegisteredEmail(unemail).save();

		}

		UnRegisteredEmail unregisteredemail = UnRegisteredEmail.find("email",
				unemail).first();

		UnregisteredInvitation invitation = new UnregisteredInvitation(msg,
				unregisteredemail, type, id);
		invitation.save();

	}

	/**
	 * sendInviteToBeID is a method that takes as params the sender and the list
	 * of receivers and using these, a new invitation to be an idea developer
	 * will be created and an invitation will be added to the list of
	 * invitations available in the User
	 * 
	 * @param sender
	 *            the one who will send the invitation
	 * @param receiver
	 *            an array list of receivers
	 * 
	 * @author Mai Selwanes
	 */

	public void sendInviteToBeIdeaDeveloper(User sender, ArrayList<User> receiver) {
		String msg = sender.name
				+ " would like to invite you to be an Idea Developer " + "in "
				+ this.name;
		String type = "ideaDeveloper";
		boolean flag = false;
		for (int i = 0; i < receiver.size(); i++) {
			// System.out.println(receiver.get(i).invitations.size());
			for (int m = 0; m < receiver.get(i).invitations.size(); m++) {

				long id = receiver.get(i).invitations.get(m).entityOrOrgId;
				long id1 = this.id;

				String message1 = receiver.get(i).invitations.get(m).message;

				if (id1 == id && msg.equals(message1)) {
					flag = true;
				}

			}
			System.out.println(flag);
			if (flag == false) {
				Invitation invitation = new Invitation(receiver.get(i), msg,
						type, this.id);
				receiver.get(i).invitations.add(invitation);
				invitation.save();
			}
		}
	}

	/**
	 * creates and return the idea that has been added directly to the
	 * Organization. it notifies the subscribers to the organization with the
	 * new idea added.
	 * 
	 * @param author
	 *            the creator of the idea
	 * 
	 * @param title
	 *            title of the new idea
	 * 
	 * @param body
	 *            body of the new idea
	 * @return idea the idea that has been created
	 * 
	 * @author Ghada Abu Shady
	 * @author Mai Selwanes only for log statement
	 * @author Heba Khattab incrementing user contribution counter
	 */
	public Idea addIdeaToOrganization(User author, String title, String body) {
		Idea idea = new Idea(author, title, body, this).save();
		this.AirIdeas.add(idea);
		String notificationBody = "" + author.name
				+ " has published the idea named " + title
				+ "in the Organization " + idea.organization.name;
		author.sendNotificationWithType(notificationBody,
				idea.organization.subscribers, "Idea", idea.id);
		idea.organization.subscribers.add(author);
		
		Log log = new Log(this, author, " has added an idea of title: " + title
				+ " to the organization");
		log.save();
		author.contributionCounter++;
		return idea;

	}
	/**
	 * takes a user and loops on orgmemebrs list and if found remove him from
	 *  the list or orgmembers and adds him to list of blockedUsers
	 * 
	 * @param User
	 *            the user which i want to block
	
	 * 
	 * @author noha wafa
	 *
	 * */
	
	public  void blockUser(User user) {
		for(int i=0;i<this.orgMembers.size();i++){
		if(user.equals(this.orgMembers.get(i))){
		this.orgMembers.remove(user);
		this.blockedUsers.add(user);
		}

		this.save();
		
	}
		}

}
